﻿using System.Collections.Generic;
using System.Linq;
using EPiBoost.Core.Infrastructure.CustomRedirects;
using EPiServer.Data.Dynamic;
using Newtonsoft.Json;

namespace EPiBoost.Core.Infrastructure.DataStore
{
    public class CustomRedirectsDataStoreHandler
    {
        private const string OLD_URL_PROPERTY_NAME = "OldUrl";
        public void SaveCustomRedirect(CustomRedirect currentCustomRedirect)
        {
            // Get hold of the datastore
            DynamicDataStore store = DataStoreFactory.GetStore(typeof(CustomRedirect));
            //check if there is an exisiting object with matching property "OldUrl"
            CustomRedirect match = store.Find<CustomRedirect>(OLD_URL_PROPERTY_NAME, currentCustomRedirect.OldUrl.ToLower()).SingleOrDefault();
            //if there is a match, replace the value.
            if (match != null)
                store.Save(currentCustomRedirect, match.Id);
            else
                store.Save(currentCustomRedirect);
        }


        /// <summary>
        /// Returns a list of all CustomRedirect objects in the Dynamic Data Store.
        /// </summary>
        /// <returns></returns>
        public List<CustomRedirect> GetCustomRedirects()
        {
            DynamicDataStore store = DataStoreFactory.GetStore(typeof(CustomRedirect));
            var CustomRedirects = from s in store.Items<CustomRedirect>().OrderBy(cr => cr.OldUrl)
                            select s;          
            return CustomRedirects != null ? CustomRedirects.ToList() : null;
        }

        public List<CustomRedirect> GetUnhandledCustomRedirects()
        {
            List<CustomRedirect> redirectList = GetCustomRedirects();
            return (redirectList.Where(r => r.HasRedirectUrl == false)).OrderByDescending(r => r.RequestCount).ToList();
        }

        public List<CustomRedirect> GetHandledCustomRedirects()
        {
            List<CustomRedirect> redirectList = GetCustomRedirects();
            return (redirectList.Where(r => r.HasRedirectUrl)).OrderBy(r => r.OldUrl).ToList();
        }


        /// <summary>
        /// Delete CustomObject object from Data Store that has given "OldUrl" property
        /// </summary>
        /// <param name="currentCustomRedirect"></param>
        public void DeleteCustomRedirect(string oldUrl)
        {
            // Get hold of the datastore
            DynamicDataStore store = DataStoreFactory.GetStore(typeof(CustomRedirect));
            
            //find object with matching property "OldUrl"
            CustomRedirect match = store.Find<CustomRedirect>(OLD_URL_PROPERTY_NAME, oldUrl.ToLower()).SingleOrDefault();
            if (match != null)
                store.Delete(match);
        }

        /// <summary>
        /// Delete all CustomRedirect objects
        /// </summary>
        public void DeleteAllCustomRedirects()
        {
            // In order to avoid a database timeout, we delete the items one by one.
            DynamicDataStore store = DataStoreFactory.GetStore(typeof(CustomRedirect));
            foreach (CustomRedirect redirect in GetCustomRedirects())
            {
                store.Delete(redirect);
            }
        }


        /// <summary>
        /// Find all CustomRedirect objects which has a OldUrl og NewUrl that contains the search word.
        /// </summary>
        /// <param name="searchWord"></param>
        /// <returns></returns>
        public List<CustomRedirect> SearchCustomRedirects(string searchWord)
        {
            DynamicDataStore store = DataStoreFactory.GetStore(typeof(CustomRedirect));
            var CustomRedirects = from s in store.Items<CustomRedirect>()
                                  where s.NewUrl.Contains(searchWord) || s.OldUrl.Contains(searchWord)
                                  select s;
            
            return CustomRedirects != null ? CustomRedirects.ToList() : null;

        }


			public string GenerateExport(List<CustomRedirect> items)
			{
				return JsonConvert.SerializeObject(items);
			}


			public int Import(string importText, bool overwriteExisting)
			{
				int importCount = 0;
				var existing = GetCustomRedirects();
				List<CustomRedirect> items = JsonConvert.DeserializeObject<List<CustomRedirect>>(importText);
				if (items != null)
				{
					foreach (var import in items)
					{
						bool exists = existing.Any(x => x.OldUrl.ToLower() == import.OldUrl.ToLower());
						if (!exists || overwriteExisting)
						{
							SaveCustomRedirect(import);
							importCount++;
						}
					}
				}
				return importCount;
			}

    }
}
